#ifndef skyBuffer_h__
#define skyBuffer_h__

#include "./skyObject.h"

namespace Sky
{
	
	class Buffer : public Object
	{
	private:
		class bufferNode
		{
		protected:
			friend class Buffer;
			u8* _buff;
			u8* _head;
			int   _len;
			int   _size;
		public:
			bufferNode(u8* buff,int size,int len):_buff(buff),_head(buff),_len(len),_size(size){}
		};
	public:
		class staticBuffer : public bufferNode
		{

		public:
			staticBuffer(u8* buff,int size,int len = 0):bufferNode(buff,size,len){}
		};

		class dynamicBuffer : public bufferNode
		{
		public:
			dynamicBuffer(u8* buff,int size,int len = 0):bufferNode(buff,size,len){}
		};

        class managedBuffer : public bufferNode
        {
        public:
            managedBuffer(u8* buff,i32 size, i32 len = 0):bufferNode(buff,size,len){}
            managedBuffer(i32 size):bufferNode((u8*)Memory::alloc(size),size,0){;}
        };
    public:
		Buffer(i32 size);
		Buffer(u8* buff,int size);
        Buffer():_buff(0),_head(0),_len(0),_size(0){}
        Buffer(staticBuffer& buff);
        Buffer(dynamicBuffer& buff);
        Buffer(managedBuffer& buff);
        Buffer(const Buffer& buff);
        Void clear();
        ~Buffer();;
        u8* getBuffer(){return _buff;}
		i32 getSize(){return _size;}
		i32 getLength(){return _len;}
	private:
		u8* _buff;
		u8* _head;
		int   _len;
		int   _size;
	};
	class Buffer;
	typedef RefPtr<Buffer> BufferPtr;
	//////////////////////////////////////////////////////////////////////////
	class BufferBuilder : public Object
	{
	public:
		BufferBuilder();
		~BufferBuilder();
		BufferBuilder* append(BufferPtr& buf);
		//BufferBuilder* append(Buffer::staticBuffer buf);
		//BufferBuilder* append(Buffer::dynamicBuffer buf);
		BufferBuilder* append(const char* buf,int size);
		BufferPtr toBuffer();
		void clear();
	private:
		class BufferNode : public Memory
		{
		public:
			BufferPtr buff;
			BufferNode* next;
		};
		BufferNode* _head;
		BufferNode* _read;
		int _totalSize;
	};
	typedef RefPtr<BufferBuilder> BufferBuilderPtr;
}

#endif // skyBuffer_h__
